#include"com.hpp"
class Udpserver
{
  public:
    Udpserver(int port)
      :_sockfd(-1)
       ,_port(port)
    //   ,_ip(ip)
  {}
    bool InitServer()
    {
      //创建套接字
      _sockfd = socket(AF_INET,SOCK_DGRAM,0); //套接字创建好了，那我们也只是在系统层面上打开了一个文件，操作系统将来并不知道是要将数据写入到磁盘还是刷到网卡，此时该文件还没有与网络关联起来。
      if(_sockfd<0)//失败
      {
        cout<<"socket error!"<<endl;
        return false;
      }
      cout<<"socket create success, sockfd:  "<<_sockfd<<endl;
      //填充网络信息
      struct sockaddr_in local;
      memset(&local,'\0',sizeof(local));
      local.sin_family=AF_INET;
      local.sin_port = htons(_port);
      //local.sin_addr.s_addr= inet_addr(_ip.c_str()); 
        local.sin_addr.s_addr= htons(INADDR_ANY); 
      //绑定
      if( bind(_sockfd,(struct sockaddr*)&local,sizeof(local))<0)
      {
        cout<<"bind fail"<<endl;
        return false;
      }
      cout<<"bind sucess"<<endl;

      return true;
    }

    void Start()
    {
      #define SIZE 128
      char buffer[SIZE];
      while(true)
      {
        struct sockaddr_in peer;
        socklen_t len = sizeof(peer);

        ssize_t size = recvfrom(_sockfd,buffer,sizeof(buffer)-1,0,(struct sockaddr*)&peer,&len);
        if(size>0)
        {
          buffer[size]='\0';
          int port = ntohs(peer.sin_port);
          string ip= inet_ntoa(peer.sin_addr);
          cout<<ip<<":"<<port<<"# "<<buffer<<endl;
        }
        else 
        {
          cout<<"recvfrom fail"<<endl;
        }

        string echo_msg="server get!->";
        echo_msg+=buffer;
        sendto(_sockfd,echo_msg.c_str(),echo_msg.size(),0,(struct sockaddr*)&peer,len);
      }
      
    }

    ~Udpserver()
    {
      if(_sockfd>=0)
      {
        close(_sockfd);
      }
    }

  private:
    int _sockfd;
    int _port;
   //string _ip;
};

int main(int argc,char* argv[])
{
  if(argc!=2)
  {
    cout<<"Usage: "<< argv[0]<<" port"<<endl;
    return 1;
  }
//  string ip="43.138.73.215";
  int port = atoi(argv[1]);

  Udpserver* svr=new Udpserver(port);
  svr->InitServer();
  svr->Start();
  return 0;
}
